package com.dxt.message;

import com.alibaba.fastjson.JSONObject;
import com.dxt.common.AppConstant;
import com.dxt.common.MyDateUtil;
import com.dxt.common.MyObjectUtil;
import com.dxt.mqtt.utils.ServerMQTTUtil;
import com.dxt.netty.utils.CRC16Util;
import com.dxt.service.CacheManager;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.util.Date;

/**
 * 错误信息处理
 */
public class ReponseMessage {
    private static final Logger logger = LoggerFactory.getLogger(Thread.currentThread().getStackTrace()[1].getClassName());

    private String code;
    private String message;
    private Object result;
    private Boolean success;
    private Long timestamp;

    public String getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }

    public Object getResult() {
        return result;
    }

    public Boolean getSuccess(){
        return success;
    }

    public Long getTimestamp(){
        return timestamp;
    }

    public ReponseMessage() {
    }

    /**
     * 睿控下发指令后判断是否成功
     * @param signStr
     * @param channel
     * @param jsonObject
     * @param message
     * @return
     */
    public ReponseMessage getReponseMessage(String signStr, Channel channel,
                                                   JSONObject jsonObject,ReponseMessage message){
        String sgin = CRC16Util.getCrc(CRC16Util.calcCrc16(signStr.getBytes()))+";";
        String reqStr = signStr+sgin;
        logger.debug("reqStr : "+ reqStr);
        ChannelFuture f = channel.writeAndFlush(reqStr);
        f.awaitUninterruptibly();
        // Now we are sure the future is completed.
        assert f.isDone();
        if (f.isCancelled()) {
            // Connection attempt cancelled by user
            logger.info("设备ID:"+jsonObject.getLong(AppConstant.REQUEST_REPONSE_PARAM.PARAM_IN_DEVICEID)+",连接通道已关闭,请稍后重试");
            message.setMsg(AppConstant.REPONSE_CODE.BUSI_WARNING,
                    "设备ID:"+jsonObject.getLong(AppConstant.REQUEST_REPONSE_PARAM.PARAM_IN_DEVICEID)+",连接通道已关闭,请稍后重试");
        } else if (!f.isSuccess()) {
            logger.error(f.cause().getMessage());
            logger.info("设备ID:"+jsonObject.getLong(AppConstant.REQUEST_REPONSE_PARAM.PARAM_IN_DEVICEID)+",下发信息失败,请稍后重试");
            message.setMsg(AppConstant.REPONSE_CODE.BUSI_WARNING,
                    "设备ID:"+jsonObject.getLong(AppConstant.REQUEST_REPONSE_PARAM.PARAM_IN_DEVICEID)+",下发信息失败,请稍后重试");
        } else {
            // Connection established successfully
            logger.info("设备ID:"+jsonObject.getLong(AppConstant.REQUEST_REPONSE_PARAM.PARAM_IN_DEVICEID)+"," + AppConstant.REPONSE_MSG.SYS_SEND_OK_MSG);
            message.setMsg(AppConstant.REPONSE_CODE.SUCCESS_CODE,
                    "设备ID:"+jsonObject.getLong(AppConstant.REQUEST_REPONSE_PARAM.PARAM_IN_DEVICEID)+","+ AppConstant.REPONSE_MSG.SYS_SEND_OK_MSG);
        }
        return message;
    }

    /**
     * 睿控TCPIP协议连接通道不存在时返回失败
     * @param jsonObject
     * @param message
     * @return
     */
    public ReponseMessage getReponseMessage(JSONObject jsonObject,ReponseMessage message){
        logger.info("设备ID:"+jsonObject.getLong(AppConstant.REQUEST_REPONSE_PARAM.PARAM_IN_DEVICEID)+",连接通道获取失败,请稍后重试");
        message.setMsg(AppConstant.REPONSE_CODE.BUSI_WARNING,
                "设备ID:"+jsonObject.getLong(AppConstant.REQUEST_REPONSE_PARAM.PARAM_IN_DEVICEID)+",连接通道获取失败,请稍后重试");
        return message;
    }

    /**
     * 和远下发指令后返回消息
     * @param cacheManager
     * @return
     */
    public ReponseMessage getReponseMessage(String signStr,String topic,String deviceId,CacheManager cacheManager,
                                            ReponseMessage message){
        //将信息写入消息体
        MqttMessage mqttMessage = new MqttMessage();
        mqttMessage.setQos(Integer.parseInt(cacheManager.getSysConfigByCode(AppConstant.SYS_CONFIG_KEY.KEY_MQTT_QOS)));
        mqttMessage.setRetained(true);
        try {
            mqttMessage.setPayload(signStr.getBytes("UTF-8"));
            ServerMQTTUtil serverMQTTUtil = new ServerMQTTUtil(topic,"server1",cacheManager);
            serverMQTTUtil.publish(mqttMessage);
        } catch (UnsupportedEncodingException e) {
            message.setMsg(AppConstant.REPONSE_CODE.SYS_ERROE,AppConstant.REPONSE_MSG.SYS_ERROR_MSG);
        } catch (MqttException e) {
            message.setMsg(AppConstant.REPONSE_CODE.SYS_ERROE,"MQTT异常");
        } catch (InterruptedException e) {
            message.setMsg(AppConstant.REPONSE_CODE.SYS_ERROE,AppConstant.REPONSE_MSG.SYS_ERROR_MSG);
        } catch (Exception e){
            message.setMsg(AppConstant.REPONSE_CODE.SYS_ERROE,AppConstant.REPONSE_MSG.SYS_ERROR_MSG);
        }
        message.setMsg(AppConstant.REPONSE_CODE.SUCCESS_CODE,AppConstant.REPONSE_MSG.SYS_SEND_OK_MSG);
        return message;
    }

    public void setMsg(String code, String message) {
        this.code = code;
        this.message = message;
        this.result = new JSONObject();
        this.success = true;
        this.timestamp = Long.parseLong(MyDateUtil.getDateStringFromDate(new Date(),
                MyDateUtil.FormatPattern.YYYYMMDDHHMMSS.getFormatPattern()));
    }

    public void setMsg(String code, String message, Object content) {
        this.code = code;
        this.message = message;
        this.result = content;
        this.success = true;
        this.timestamp = Long.parseLong(MyDateUtil.getDateStringFromDate(new Date(),
                MyDateUtil.FormatPattern.YYYYMMDDHHMMSS.getFormatPattern()));
    }

    public void setMsg(String code, String message,Boolean success,Long timestamp) {
        this.code = code;
        this.message = message;
        this.result = new JSONObject();
        this.success = success;
        this.timestamp = timestamp;
    }

    public void setMsg(String code, String message, Object result,Boolean success,Long timestamp) {
        this.code = code;
        this.message = message;
        this.result = result;
        this.success = success;
        this.timestamp = timestamp;
    }

    @Override
    public String toString() {
        return MyObjectUtil.show(this);
    }
}
